import { _decorator, Component, instantiate, tween, Vec3, Node, Prefab, random} from 'cc';
import { Card } from "./Card";
import { PlayerManager } from "./PlayerManager";
import { CardManager } from './CardManager';

import  logic from "./CardLogic";
import { Zjmj3D, Layer } from "./StaticDefine";
import  Util  from './Util';

const { ccclass, property } = _decorator;

@ccclass('HandCard') // 用 @ccclass 声明类为 Cocos 组件
export class HandCard extends Component {

    @property index: number = -1;
    @property(Prefab) cardPerfab: Prefab | null = null;

    public mySeat: boolean = false;

    public cardIDs: number[] = [];
    public exileCard: Node | null = null;

    private selectIndex = -1;
    private playCarding = false;

    onLoad(): void {
    }

    public onReset() {

        this.node.removeAllChildren();

        this.cardIDs = [];
        this.exileCard = null;

        this.randomCardData();
    }

    public startCard() {
        this.initCards();
        this.drawStartCards();
    }

    public selectCard(index: number) {

        if(this.selectIndex == index)
        {        
            if(logic.ExistExileCard(this.cardIDs))
            {
                this.playCard();
                // this.selectIndex = -1;
            }    
             
        }
        else
        {
            this.selectIndex = index;
            this.syncSelection();

            const cardNode = this.node.children[this.selectIndex];
            if(cardNode)
            {
                const card: Card | null = cardNode.getComponent(Card);
                if(card)
                {
                    // card.setArrow( Util.getRandomNumber(0, 3) );
                    card.emitMyEvent(card.cardID);
                }
            }
        }
    }

    public drawCard(cardID:number = 0) {

        
        if(cardID == 0)
        {
            cardID = Util.randomCardID();
        }
        // if(this.mySeat)
        // {
        //     console.log("drawCard...", cardID);
        // }
        //data
        const exileIndex = logic.exileCardIndex(this.cardIDs);
        this.cardIDs[exileIndex] = cardID;

        //object
        if(this.exileCard)
        {
            this.exileCard.removeFromParent();
            this.exileCard = null;
        }

        this.drawCardAnimation(cardID);

        //link
        // GameManager.getDeck().RemoveCurrentCard();
    }

    public playCard() {
        if(this.playCarding == true || logic.ExistExileCard(this.cardIDs) == false)
        {
            return;
        }

        if(this.mySeat == false)
        {
            this.selectIndex = this.cardIDs.length - 1;
        }

        //data
        this.cardIDs.splice(this.selectIndex, 1);
        logic.sortCards(this.cardIDs);

        //object
        this.playCardAnimation();
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    createCard() : Node | null {
        if(this.cardPerfab == null)
        {
            return null;
        }
        const cardNode = CardManager.createHandCard(this.mySeat);
        return cardNode;
    }

    getCard(index:number) {
        // console.log("this...",this);
        return this.node.children[index];
    }

    randomCardData() {

        this.cardIDs = [];

        let cardCount = Zjmj3D.StartCard;
        // const bBank = random() > 0.5;
        const bBank = this.mySeat;
        if(bBank)
            cardCount = Zjmj3D.GameCard;

        for(let i = 0; i < cardCount; i++)
        {
            let cardID = Util.randomCardID();
            this.cardIDs.push(cardID);
        }

        // this.cardIDs = [311, 371, 351, 331, 361, 352, 372, 381, 341, 353, 342, 373, 391, 354];

        // this.cardIDs = [311, 371, 351, 331, 361, 352, 372, 381, 341, 353, 342, 373, 391];

        // console.log("randomCardData", this.cardIDs);
    }


    isSidePlayer() {
        const index = PlayerManager.instance.mySiteIndex;
        return Math.abs(this.index - index) == 1 || Math.abs(this.index - index) == 3;
    }

    cardPos(i:number) {
        return logic.getCardPosition(i, this.cardIDs, this.isSidePlayer() );
    }

    syncDate() {
        
        let cache = this.node.children.slice();
        this.node.removeAllChildren();

        const cardIDs = this.cardIDs;
        for(let i = 0; i < cardIDs.length; i++)
        {
            let model = null;
            for(let j = 0; j < cache.length; j++)
            {
                if(cache[j].getComponent(Card)?.cardID == cardIDs[i])
                {
                    model = cache[j];
                    // cache = cache.slice(j, 1);
                    break;
                }
            }

            if(model == null)
            {
                model = this.createCard();
                if(model)
                {
                    const card: Card | null = model.getComponent(Card);
                    if(card)
                    {
                        card.cardID = cardIDs[i];
                    }
                }
            }

            if(model)
            {
                model.position = this.cardPos(i);
                model.eulerAngles = logic.getCardAngle();
                this.node.addChild(model);
            }
        }

        if(logic.ExistExileCard(cardIDs))
        {
            this.exileCard = this.node.children[cardIDs.length - 1]
        }
    }

    initCards() {
        this.syncDate();
        for(let i = 0; i < this.node.children.length; i++)
        {
            const cardNode = this.node.children[i];
            if(cardNode)
            {
                cardNode.active = false;
            }
        }
    }

    drawStartCards() {
        // console.log("drawStartCards...");
        this.scheduleOnce(()=> {
            this.startDrawStep();
        });

        if(this.cardIDs.length == Zjmj3D.GameCard)
        {
            this.scheduleOnce(()=>{ this.drawCard(this.cardIDs[Zjmj3D.GameCard-1]); }, 1.4);
        }

        if(this.mySeat)
        {
            this.switchViewprot(true);
            this.scheduleOnce(()=>{ this.sortStartCards(); }, 1.8);
        }
    }

    startDrawStep() {
        this.rotateCards(0, Zjmj3D.StartCard);
    }

    rotateCards(start: number, max: number) {

        let startIndex = start;
        let endIndex = startIndex + 4;
        if(endIndex > max)
            endIndex = max;

        for (let i = startIndex; i < endIndex; i++) {
            const cardNode = this.getCard(i);
            if (cardNode) {
                cardNode.active = true; // 激活牌
                const card = cardNode.getComponent(Card);
                if(card)
                {
                    card.openCard( () => {
                        let index = i;
                        if(index == endIndex - 1 && endIndex < max)
                        {
                            startIndex += 4;
                            if(startIndex >= max)
                                startIndex = max - 1;
                                        
                            this.rotateCards(startIndex, max); // 翻转接下来的四张
                        }
                    });
                }
            }
        }
    }


    sortStartCards() {

        for(let i = 0; i < this.cardIDs.length; i++)
        {
            const cardNode = this.getCard(i);
            if(cardNode)
            {
                cardNode.active = true; // 激活牌
                const card = cardNode.getComponent(Card);
                if(card)
                {
                    if(i == 0)
                    {
                        // const self = this;
                        // card.closeCard( () => {
                        //     console.log("sortStartCards!!!!!!!!!!!!!!", this);
                        //     self.sortCards(13);
                        //     for(let j = 0; j < self.cardIDs.length; j++)
                        //     {
                        //         const newNode = self.getCard(j);
                        //         if(newNode)
                        //         {
                        //             const newCard = newNode.getComponent(Card);
                        //             newCard?.openCard();
                        //         }
                        //     }
                        // });
                        card.closeCard( () => { card.openCard(); this.sortCards(13); } );
                    }
                    else
                    {
                        card.closeCard( () => { card.openCard() } );
                    }
                }
            }
        }
    }

    sortCards(sortCount:number = 0) {

        if(sortCount == 0)
        {
            sortCount = this.node.children.length;
        }

        const cardIDs = this.cardIDs;
        const sortIDs = cardIDs.slice(0, sortCount);
        logic.sortCards(sortIDs);
        if(cardIDs.length > sortCount)
        {
            for(let i = sortCount; i < cardIDs.length; i++)
            {
                sortIDs[i] = cardIDs[i];
            }
        }
        this.cardIDs = sortIDs;

        this.syncDate();
    }


    sortCards2(sortCount:number = 0) {

        if(sortCount == 0)
        {
            sortCount = this.node.children.length;
        }

        //for node
        const cards = this.node.children;
        let nosortCard = [];
        // 只排序前N张
        const sortedCards = cards.slice(0, sortCount);
        if(cards.length > sortCount)
        {
            for(let i = sortCount; i < cards.length; i++)
            {
                nosortCard.push(cards[i]);
            }
        }

        this.node.removeAllChildren();

        // 根据卡牌的 ID 进行排序
        sortedCards.sort((a, b) => {
            const cardA = a.getComponent(Card);
            const cardB = b.getComponent(Card);
            return (cardA?.cardID || 0) - (cardB?.cardID || 0); // 确保 ID 存在
        });

        // 更新子节点的索引和位置
        sortedCards.forEach((cardNode, index) => {
            this.node.addChild(cardNode); // 重新添加以更新索引
            cardNode.position = this.cardPos(index);
        });

        if(sortedCards.length > 0)
        {
            for(let i = 0; i < nosortCard.length; i++)
            {
                this.node.addChild(nosortCard[i]);// 重新添加以更新索引
            }
        }

        //for data
        const cardIDs = this.cardIDs;
        const sortIDs = cardIDs.slice(0, sortCount);
        sortIDs.sort();
        if(cardIDs.length > sortCount)
        {
            for(let i = sortCount; i < cardIDs.length; i++)
            {
                sortIDs[i] = cardIDs[i]
            }
        }
        this.cardIDs = sortIDs;
    }

    syncSelection() {
        const cards = this.node.children;
        const count = cards.length;
        for(let i = 0; i < count; i++)
        {
            const cardNode = cards[i]
            if(cardNode)
            {
                let pos = cardNode.position;
                if(i == this.selectIndex)
                {
                    cardNode.position = new Vec3(pos.x, 0.01, pos.z);
                }
                else
                {
                    cardNode.position = new Vec3(pos.x, 0, pos.z);
                }
            }
        }
    }

    drawCardAnimation(cardID:number) {

        const model = this.createCard();
        if(model)
        {
            const card: Card | null = model.getComponent(Card);
            if(card)
            {
                card.cardID = cardID;
            }

            const start = logic.getExileCardPosition(this.cardIDs);
            start.y += 0.05;
            const end = logic.getExileCardPosition(this.cardIDs);

            model.eulerAngles = logic.getCardAngle();
            this.node.addChild(model);

            model.position = start; // 初始位置
            tween(model)
            .to(0.3, { 
                position: end // 设置新的位置
            })
            .call(() => {
                if(this.mySeat == false)
                {
                    this.scheduleOnce(this.playCard, 0.3);
                }
            })
            .start();

            this.exileCard = model;

            model.active = true;
        }
    }

    // playCardAnimation() {
    //     const cards = this.node.children;
    //     const card = cards[this.node.children.length - 1];
    //     if(card)
    //     {
    //         let pos = card.position;
    //         tween(card)
    //         .to(0.1, {position: new Vec3(pos.x, 0.04, pos.z)})
    //         .call(()=>{
    //             card.removeFromParent();
    //             // GameManager.getOut().onOutCard(this.index, -1);
    //             // this.scheduleOnce(this.autoNextPlayer, 0.3);
    //         })
    //         .start();
    //     }
    // }

    playCardAnimation() {
        const cards = this.node.children;
        const cardNode = cards[this.selectIndex];
        if(cardNode)
        {
            const card = cardNode.getComponent(Card);

            this.playCarding = true;
            let pos = cardNode.position;
            tween(cardNode)
            .to(0.1, {position: new Vec3(pos.x, 0.04, pos.z)})
            .call(()=>{
                cardNode.removeFromParent();
                // GameManager.getOut().onOutCard(0, card!.cardID);
                // this.scheduleOnce(this.autoNextPlayer, 0.3);

                this.exileCard = null;
                if(this.selectIndex != this.cardIDs.length)
                {
                    this.getCloseAnimation();
                    this.insertCardAnimation();
                }
                else
                {
                    this.playCarding = false;
                }

            })
            .start();
        }
    }

    getCloseAnimation() {

        const cards = this.node.children;
        for(let i = 0; i < cards.length; i++)
        {
            if(i == cards.length - 1)
            {
                continue;//do insert
            }
            const model = cards[i];
            if(model)
            {
                let index = i;
                const card: Card | null = model.getComponent(Card);
                if(card)
                {
                    const cardID = card.cardID;
                    const newIndex = this.cardIDs.indexOf(cardID);
                    if(newIndex != -1)
                    {
                        index = newIndex;
                    }
                }

                const pos = this.cardPos(index);
                tween(model)
                .to(0.1, {position: pos})
                .start();
            }
        }
    }

    insertCardAnimation() {
        const cards = this.node.children;
        const model = cards[cards.length - 1];
        if(model)
        {
            const card: Card | null = model.getComponent(Card);
            if(card)
            {
                card.liftCard( ()=>{
                    let index = cards.length - 1;
                    const cardID = card.cardID;
                    const newIndex = this.cardIDs.indexOf(cardID);
                    if(newIndex != -1)
                    {
                        index = newIndex;
                    }
                    const pos = this.cardPos(index);
                    // cardNode.position = pos;
                    tween(model)
                    .to(0.1, {position: pos})
                    .call(()=>{
                        card.dropCard( ()=>{
                            this.sortCards();
                            this.playCarding = false;
                        });
                    })
                    .start();
                });
            }
        }

    }

    showRemainCards() {

        this.switchViewprot(false);

        const count = this.node.children.length;
        for(let i = 0; i < count; i++)
        {
            const cardNode = this.getCard(i);
            if(cardNode)
            {
                const card = cardNode.getComponent(Card);
                if(card)
                {
                    card.showCard();
                }
            }
        }
    }

    switchViewprot(bFirst:boolean) {
        if(bFirst)
        {
            Util.setLayerRecursively(this.node, Layer.HANDCARD);
        }
        else
        {
            Util.setLayerRecursively(this.node, Layer.DESKTOP);
        }
        
    }



}